import React, { Component } from "react";
import { connect } from "react-redux";
import DepartmentUI from "components/template/department/department.UI";
import { Checkbox, Badge, message, Popover } from "antd";
import httpFetch from "share/httpFetch";
import { deepFullCopy, messages } from "share/common";

@connect(mapStateToProps)
class DepartmentBS extends Component {
  allData = [];

  onSelectChange = (selectedRowKeys) => {
    let { rowSelection } = this.state;
    rowSelection.selectedRowKeys = selectedRowKeys;
    this.setState({ rowSelection });
  };

  onSelectItem = (record, selected) => {
    const { rowSelection, checkedValue } = this.state;
    const { single } = this.props;
    if (single) {
      rowSelection.selectedData = [record];
    } else {
      if (selected) {
        if (checkedValue.indexOf("checked") > -1) {
          let addList = this.treeNodeToArr([record], []);
          addList.forEach((item) => rowSelection.selectedData.addIfNotExistObj(item, "id"));
          rowSelection.selectedRowKeys = rowSelection.selectedData.map((item) => item.id);
        } else {
          rowSelection.selectedData.push(record);
        }
      } else {
        if (checkedValue.indexOf("checked") > -1) {
          let deleteList = this.treeNodeToArr([record], []);
          deleteList.forEach((item) => rowSelection.selectedData.deleteObj(item, "id"));
          rowSelection.selectedRowKeys = rowSelection.selectedData.map((item) => item.id);
        } else {
          rowSelection.selectedData.deleteObj(record, "id");
        }
      }
    }
    this.setState({ rowSelection });
  };

  treeNodeToArr = (arr, res) => {
    arr.map((item) => {
      res.push(item);
      res = this.treeNodeToArr(item.children || [], res);
    });
    return res;
  };

  onSelectAll = (selected) => {
    let { rowSelection, checkedValue, data } = this.state;
    if (selected) {
      rowSelection.selectedData =
        checkedValue.indexOf("enabled") > -1
          ? this.allData.slice()
          : this.allData.filter((item) => item.status === 101);
    } else {
      rowSelection.selectedData = [];
    }
    rowSelection.selectedRowKeys = rowSelection.selectedData.map((item) => item.id);
    this.setState({ rowSelection });
  };

  state = {
    checkedValue: [],
    rowSelection: {
      selectedRowKeys: [],
      onChange: this.onSelectChange,
      onSelect: this.onSelectItem,
      onSelectAll: this.onSelectAll,
      selectedData: [],
      type: this.props.single ? "radio" : "checkbox",
    },
    loading: false,
    data: [],
    showData: [],
    page: 1,
    total: 0,
  };

  size = 20;

  componentDidMount() {
    const { onRef } = this.props;
    onRef && onRef(this);
  }

  searchValues = {};

  service = (values, init) => {
    if (init) {
      this.getDepartment().then(() => {
        let temp = this.arrTurnToTree();
        this.setState(
          {
            data: temp,
            showData: temp.slice(0, this.size),
            page: 1,
          },
          this.handleValue
        );
      });
    } else {
      if (values.companyOID !== this.searchValues.companyOID) {
        this.getDepartment(values.companyOID).then(() => {
          this.searchValues = values;
          let { temp, length } = this.handleSearchTree(this.arrTurnToTree());
          this.setState({ data: temp, showData: temp.slice(0, this.size), page: 1 }, this.uiRef.clearScroll);
        });
      } else {
        this.searchValues = values;
        let { temp, length } = this.handleSearchTree(this.arrTurnToTree());
        this.setState({ data: temp, showData: temp.slice(0, this.size), page: 1 }, this.uiRef.clearScroll);
      }
    }
  };

  invalidData = [];

  handleValue = () => {
    const { rowSelection } = this.state;
    const { value, parser } = this.props;
    (value || []).map((item) => {
      let temp = this.allData.find((record) => {
        let temp = parser(record);
        return (temp.id && temp.id === item.id) || (temp.departmentOID && temp.departmentOID === item.departmentOID);
      });
      if (temp) {
        rowSelection.selectedData.push(temp);
        rowSelection.selectedRowKeys.push(temp.id);
      } else {
        this.invalidData.addIfNotExistObj(item, "id");
      }
    });
    this.uiRef.clearScroll();
    this.setState({ rowSelection });
  };

  getDepartment = (companyOID) => {
    const { isNeedCompany, company } = this.props;
    return new Promise((resolve, reject) => {
      this.setState({ loading: true });
      httpFetch
        .get(`/api/department/tenant/all`, {
          roleType: "TENANT",
          companyOID: companyOID || (isNeedCompany ? company.companyOID : undefined),
        })
        .then((res) => {
          this.allData = res.data;
          this.setState({ loading: false });
          resolve();
        })
        .catch((e) => {
          this.setState({ loading: false });
          message.error(e.response.data.message);
          reject();
        });
    });
  };

  arrTurnToTree = () => {
    const { checkedValue } = this.state;
    let nowData =
      checkedValue.indexOf("enabled") > -1 ? this.allData : this.allData.filter((item) => item.status === 101);
    let arr = { nullValue: [] };
    for (let i = 0; i < nowData.length; i++) {
      let item = deepFullCopy(nowData[i]),
        { parentId } = item;
      if (parentId) {
        if (arr.hasOwnProperty(parentId)) {
          arr[parentId].push(item);
        } else {
          arr[parentId] = [item];
        }
      } else {
        arr.nullValue.push(item);
      }
    }
    Object.keys(arr).forEach((item) => {
      if (item !== "nullValue") {
        Object.keys(arr).forEach((record) => {
          if (record !== item) {
            arr[record].every((obj) => {
              if (obj.id === item) {
                obj.children = arr[item];
                return false;
              } else if (obj.hasOwnProperty("children")) {
                return this.handleChildren(obj, item, arr[item]);
              }
              return true;
            });
          }
        });
        delete arr[item];
      }
    });
    return arr.nullValue;
  };

  handleChildren = (obj, id, list) => {
    let flag = true;
    obj.children.every((item) => {
      if (item.id === id) {
        item.children = list;
        flag = false;
        return false;
      } else if (item.hasOwnProperty("children")) {
        flag = this.handleChildren(item, id, list);
        return flag;
      }
      return true;
    });
    return flag;
  };

  handleSearchTree = (list, total = 0) => {
    let arr = [];
    const { name = "", custDeptNumber = "" } = this.searchValues;
    for (let i = 0; i < list.length; i++) {
      let item = list[i];
      if (item.name.indexOf(name) > -1 && (item.custDeptNumber || "").indexOf(custDeptNumber) > -1) {
        if (item.hasOwnProperty("children")) {
          let { temp, length } = this.handleSearchTree(item.children);
          if (temp.length) {
            total += length;
            item.children = temp;
          } else {
            delete item.children;
          }
        }
        arr.push(item);
        total += 1;
      } else {
        if (item.hasOwnProperty("children")) {
          let { temp, length } = this.handleSearchTree(item.children);
          if (temp.length) {
            item.children = temp;
            total += length;
            arr.push(item);
          }
        }
      }
    }
    return { temp: arr, length: total };
  };

  onScrollEvent = () => {
    let { data, showData, page } = this.state;
    if (page * this.size >= data.length) {
      return -1;
    }
    showData = showData.concat(data.slice(page * this.size, page * this.size + this.size));
    this.setState({ showData, page: ++page });
  };

  renderNameByKey = (value) => {
    const { name } = this.searchValues;
    let result = [];
    let sections = value.split(name);
    sections.map((item, index) => {
      result.push(item);
      if (index !== sections.length - 1) {
        result.push(
          <span style={{ color: "#ff6680" }} key={index}>
            {name}
          </span>
        );
      }
    });
    return result;
  };

  columns = [
    {
      title: messages("common-1.key708") /*部门名称*/,
      dataIndex: "name",
      render: (value) => <Popover content={value}>{this.renderNameByKey(value)}</Popover>,
    },
    {
      title: messages("common-1.key709") /*部门编码*/,
      dataIndex: "custDeptNumber",
      width: 160,
      render: (value) => <Popover content={value}>{value}</Popover>,
    },
    {
      title: messages("common.column.status") /*状态*/,
      dataIndex: "status",
      width: 92,
      render: (value) => (
        <Badge
          status={value === 101 ? "success" : "error"}
          text={value === 101 ? messages("common-1.key1468") /*启用中*/ : messages("common-1.key1469") /*已停用*/}
        />
      ),
    },
  ];

  handleCheck = (checkedValue) => {
    let flag =
      (checkedValue.indexOf("enabled") > -1 && this.state.checkedValue.indexOf("enabled") === -1) ||
      (checkedValue.indexOf("enabled") === -1 && this.state.checkedValue.indexOf("enabled") > -1);
    this.setState({ checkedValue }, () => {
      flag && this.service(this.searchValues);
    });
  };

  handleOk = () => {
    const { rowSelection } = this.state;
    const { parser } = this.props;
    return rowSelection.selectedData.map((item) => parser(item)).concat(this.invalidData);
  };

  render() {
    const { showData, loading, rowSelection, total } = this.state;
    const { getExtraSearch, hideSubDepartment, single, showAllName, options, showDisabled } = this.props;
    let extraSearch = getExtraSearch();
    const searchForm = [
      { label: messages("common-1.key708") /*部门名称*/, id: "name", component: "Input" },
      { label: messages("common-1.key709") /*部门编码*/, id: "custDeptNumber", component: "Input" },
    ];
    const option = [];
    if (extraSearch) {
      searchForm.push({
        label: messages("common-1.key423") /*公司*/,
        id: "companyOID",
        component: extraSearch,
        parser: (value) => ({ companyOID: value && value.length && value[0].key }),
      });
    }
    if (!hideSubDepartment && !single) {
      option.push({ label: messages("common-1.key1470") /*选中包含子部门*/, value: "checked" });
    }
    if (showDisabled) {
      option.push({ label: messages("common-1.key1471") /*显示已停用部门*/, value: "enabled" });
    }
    return (
      <DepartmentUI
        searchForm={searchForm}
        service={this.service}
        data={showData}
        loading={loading}
        onScrollEvent={this.onScrollEvent}
        onRef={(uiRef) => (this.uiRef = uiRef)}
        rowSelection={rowSelection}
        columns={this.columns}
        total={total}
        showAllName={showAllName || options["department"]["fullPathDisabled"] === "false"}
      >
        {option.length > 0 && (
          <div>
            <Checkbox.Group options={option} onChange={this.handleCheck} />
          </div>
        )}
      </DepartmentUI>
    );
  }
}

function mapStateToProps(state) {
  return {
    company: state.login.company,
    options: state.login.options,
  };
}

export default DepartmentBS;
